package com.dyrj.pig.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dyrj.jzb.po.*;
import com.dyrj.jzb.service.JzbApiService;
import com.dyrj.pig.bean.*;
import com.dyrj.pig.dao.*;
import com.dyrj.pig.result.JsonResult;
import com.dyrj.pig.service.TYskPayService;
import com.dyrj.ysk.configuration.SdkProperties;
import com.dyrj.ysk.exception.BizException;
import com.dyrj.ysk.service.SignService;
import com.dyrj.ysk.util.CusAccessObjectUtil;
import com.dyrj.ysk.util.FakeDataUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName: TYskPayController
 * @Description:5.2	支付后台通知
 * 付款人在银联页面支付成功后，云收款系统异步接收银联的后端通知结果，处理完成后，异步通知商户支付结果，商户需要接收处理，并返回应答。
 * 交易数据将以POST方法json格式发送给交易时上送的后台通知地址URL，客户端返回“notify_success”表示接收成功。
 * 通知策略：如果云收款收到商户的应答不是成功或超时，云收款认为通知失败，云收款会通过一定的策略定期重新发起通知，尽可能提高通知的成功率，但不保证通知最终能成功（通知频率为5/5/10/30/60/60/60/60/60/60，单位：秒）。
 * 注意：同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。
 * 推荐的做法是，商户在接收后台回调通知时验签通过后，需先判断回调报文中的订单状态，判断该通知是否已经处理过，如果没有处理过再进行处理，如果处理过直接返回结果成功。
 * 在对业务数据进行状态检查和处理之前，要采用数据锁进行并发控制，以避免函数重入造成的数据混乱。
 * @author cyberdolphin
 */
@Controller
@RequestMapping("/ysk/pay")
@Slf4j
public class TYskPayController {
	//    private static SimpleDateFormat sdf_datetime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	private static SimpleDateFormat sdf_datetime = new SimpleDateFormat("yyyyMMddHHmmss");
	private DecimalFormat df = new DecimalFormat("0.00");

	@Resource
	private TYskPayService service;
	@Resource
	private SdkProperties sdkProperties;
	@Resource
	private SignService signService;
	@Resource
	private TRecordPayMapper tRecordPayMapper;
	@Resource
	private TYskPayMapper tYskPayMapper;
	@Resource
	private TUserMapper tUserMapper;
	@Resource
	private JzbApiService jzbApiService;
	@Resource
	private TJzbFreezeMapper tJzbFreezeMapper;
	@Resource
	private TRecordDrawcashMapper tRecordDrawcashMapper;


	@RequestMapping(value = "/getqianbao",method = RequestMethod.GET)
	@ResponseBody
	public JsonResult<Map> getQianBao(String membercode){
		log.info("getQianBao membercode is {}",membercode);
		JsonResult<Map> result = new JsonResult<>();
		//充值后更新余额和提现金额
		//SubAcctAvailBal
		Map<String,String> map_qianbao = getJzbQianBaoMap(membercode);
//		String acctavailbal = map_qianbao.get("acctavailbal");
//		String cashamt = map_qianbao.get("cashamt");
		result.setData(map_qianbao);
		result.setStatus(0);
		result.setInfo("success");
		return result;
	}

	//申请提现或支付短信动态码
	@RequestMapping(value = "/gettixiansmscode",method = RequestMethod.POST)
	@ResponseBody
	public JsonResult<Map> getTixianSmsCode(String yhbm, String subacctno, String membercode,String bankcardno, String tranamt){
		log.info("getTixianSmsCode yhbm is {}",yhbm);
		log.info("getTixianSmsCode subacctno is {}",subacctno);
		log.info("getTixianSmsCode membercode is {}",membercode);
		log.info("getTixianSmsCode bankcardno is {}",bankcardno);
		log.info("getTixianSmsCode tranamt is {}",tranamt);
		JsonResult<Map> result = new JsonResult<>();
		Map<String,String> map_rtn = new HashMap<>();
		/*
		 * subAcctNo 见证子账户的账号
		 * tranType 交易类型 1：提现 2：支付 3：批次号支付 4：批次号作废
		 * tranAmt 交易金额 按批次号提现时非必输
		 * bankCardNo 银行卡号
		 * orderNo 订单号 按批次号提现时，此字段必须，上送批次号字段
		 */
		String tranType="1";
		String orderNo="";

		Double dbl_tranamt = Double.valueOf(tranamt);
		String str_tranamt = df.format(dbl_tranamt);

		Po6082ApplicationTextMsgDynamicCode po6082ApplicationTextMsgDynamicCode = jzbApiService.Api6082ApplicationTextMsgDynamicCode(subacctno, membercode, tranType, str_tranamt, bankcardno, orderNo);
		if(po6082ApplicationTextMsgDynamicCode!=null && "000000".equals(po6082ApplicationTextMsgDynamicCode.getTxnReturnCode())){
			map_rtn.put("receivemobile",po6082ApplicationTextMsgDynamicCode.getReceiveMobile());
			map_rtn.put("messageorderno",po6082ApplicationTextMsgDynamicCode.getMessageOrderNo());
			result.setData(map_rtn);
			result.setCode(0);
			result.setMsg("success");
		}else{
			result.setCode(-1);
			result.setMsg(po6082ApplicationTextMsgDynamicCode.getTxnReturnMsg());
		}

		return result;
	}

	//会员提现-支持手续费
	@RequestMapping(value = "/gettixianprocess",method = RequestMethod.POST)
	@ResponseBody
	public JsonResult<Map> getTixianProcess(String subacctno,String subacctname, String membercode,String takecashacctno, String takecashacctname, String tranamt, String messageorderno, String messagecheckcode){
		log.info("getTixianSmsCode subacctno is {}",subacctno);
		log.info("getTixianSmsCode subacctname is {}",subacctname);
		log.info("getTixianSmsCode membercode is {}",membercode);
		log.info("getTixianSmsCode takecashacctno is {}",takecashacctno);
		log.info("getTixianSmsCode takecashacctname is {}",takecashacctname);
		log.info("getTixianSmsCode tranamt is {}",tranamt);
		log.info("getTixianSmsCode messageorderno is {}",messageorderno);
		log.info("getTixianSmsCode messagecheckcode is {}",messagecheckcode);
		JsonResult<Map> result = new JsonResult<>();
		Map<String,String> map_rtn = new HashMap<>();

		/*
		 * subAcctNo	        见证子账户的账号
		 * tranNetMemberCode	市场的会员代码
		 * subAcctName	        见证子账户的户名
		 * takeCashAcctNo	    收款账户的账号
		 * takeCashAcctName	    收款账户的户名
		 * cashAmt	            申请提现的金额
		 * messageOrderNo	    短信验证码指令号
		 * messageCheckCode	    短信验证码
		 */
		String takeCashCommission="0.00";
		Po6085MemberWithdrawCash po6065UnbindRelateAcct = jzbApiService.Api6085MemberWithdrawCash(subacctno, membercode, subacctname,takecashacctno,takecashacctname,tranamt,takeCashCommission,messageorderno,messagecheckcode);
		if(po6065UnbindRelateAcct!=null && "000000".equals(po6065UnbindRelateAcct.getTxnReturnCode())){
			result.setCode(0);
			result.setMsg("success");

			try{
				//得到用户
				QueryWrapper<TUser> queryWrapper = new QueryWrapper<>();
				queryWrapper.eq("membercode",membercode);
				TUser tuser = tUserMapper.selectOne(queryWrapper);

				int int_tranamt = Integer.valueOf(tranamt)*100;
				TRecordDrawcash tRecordDrawcash = new TRecordDrawcash();
				tRecordDrawcash.setUserid(tuser.getYhbm().toString());
				tRecordDrawcash.setSubno(subacctno);
				tRecordDrawcash.setDrawtime(new Date());
				tRecordDrawcash.setCashamt(int_tranamt);
				tRecordDrawcash.setTakecashacctno(takecashacctno);
				tRecordDrawcash.setTakecashacctname(takecashacctname);
				tRecordDrawcash.setFrontseqno(po6065UnbindRelateAcct.getFrontSeqNo());
				tRecordDrawcashMapper.insertSelective(tRecordDrawcash);
			}catch (Exception e){
				e.printStackTrace();
			}



		}else{
			result.setCode(-1);
			result.setMsg(po6065UnbindRelateAcct.getTxnReturnMsg());
		}
		return result;
	}

	/**
	 * CLOUDPAY6005
	 * 商户支付后台通知地址
	 * @param request
	 * @param response
	 * @throws IOException
	 * @throws BizException
	 */
	@RequestMapping(value = "/notify",method = RequestMethod.POST)
	@ResponseBody
	public void payNotifyUrl(HttpServletRequest request, HttpServletResponse response) throws IOException, BizException {
		log.debug("payNotifyUrl_beg");
		Map<String,String> params= CusAccessObjectUtil.getAllRequestParam(request);
		log.info(params.toString());

		/*
{
TranAmt=50,
TraderNo=480806921546560148,
ChannelOrderNo=672010212104258575278,
OrderStatus=1,
OrderType=1,
PayCardType=1,
PaySuccessTime=20201021211236,
BankOrderNo=2010212112285490011000051,
OrderSendTime=20201021210425,
PayModeNo=FastPay,
TraderOrderNo=1603285465784oc7g8u6chDXcjaf
}
		 */
		String TraderNo = params.get("TraderNo");
		String TranAmt = params.get("TranAmt");
		String TraderOrderNo = params.get("TraderOrderNo");
		String BankOrderNo = params.get("BankOrderNo");
		String PayModeNo = params.get("PayModeNo");
		String OrderType = params.get("OrderType");
		String OrderStatus = params.get("OrderStatus");
		String OrderSendTime = params.get("OrderSendTime");
		String ChannelOrderNo = params.get("ChannelOrderNo");
		String PaySuccessTime = params.get("PaySuccessTime");
		String PayCardType = params.get("PayCardType");

		TYskPayExample tYskPayExample = new TYskPayExample();
		TYskPayExample.Criteria criteria = tYskPayExample.createCriteria();
		criteria.andTraderordernoEqualTo(TraderOrderNo);
		List<TYskPay> list_tYskPay_db = tYskPayMapper.selectByExample(tYskPayExample);

		if(list_tYskPay_db!=null && list_tYskPay_db.size()>0){
			TYskPay tYskPay_db = list_tYskPay_db.get(0);

			//充值后更新余额和提现金额
			Map<String,String> map_qianbao = getJzbQianBaoMap(tYskPay_db.getClientno());

			try{
				Date now = new Date();
				TYskPay tYskPay = new TYskPay();
				tYskPay.setId(tYskPay_db.getId());
				tYskPay.setBankorderno(BankOrderNo);
				tYskPay.setPaymodeno(PayModeNo);
				tYskPay.setOrdertype(OrderType);
				tYskPay.setOrderstatus(OrderStatus);
				tYskPay.setOrdersendtime(OrderSendTime);
				tYskPay.setChannelorderno(ChannelOrderNo);
				tYskPay.setPaycardtype(PayCardType);
				tYskPay.setUpdatetime(now);
				tYskPayMapper.updateByPrimaryKeySelective(tYskPay);
			}catch (Exception e){
				e.printStackTrace();
			}

			try{
				TRecordPay tRecordPay = new TRecordPay();
				tRecordPay.setUserid(tYskPay_db.getUserid());
				tRecordPay.setRechartmoney(Integer.valueOf(TranAmt));
				tRecordPay.setTraderorderno(TraderOrderNo);
				if(PaySuccessTime!=null && !"".equals(PaySuccessTime)){
					try{
						tRecordPay.setRechardtime(sdf_datetime.parse(PaySuccessTime));
					}catch (Exception e){
						e.printStackTrace();
					}
				}

				tRecordPay.setSubno(tYskPay_db.getSubaccno());
				tRecordPay.setCnsmrseqno(TraderNo);
//				tRecordPay.setStatus();
				tRecordPayMapper.insertSelective(tRecordPay);
			}catch (Exception e){
				e.printStackTrace();
			}

			//根据用户类型，确定是否调用冻结接口，类型0用户1屠宰户2养殖户3司机
			//得到用户
			TUser tuser = null;
			try{
				QueryWrapper<TUser> queryWrapper = new QueryWrapper<>();
				queryWrapper.eq("membercode",tYskPay_db.getClientno());
				tuser = tUserMapper.selectOne(queryWrapper);
			}catch (Exception e){
				e.printStackTrace();
			}

			//paymodel=0，冻结方式充值
			if(tuser!=null && tuser.getPaymodel().equals("0")){
				String functionFlag="1";
				String subAcctNo=tYskPay_db.getSubaccno();
				String tranNetMemberCode=tYskPay_db.getClientno();
				Double db_TranAmt = Double.valueOf(TranAmt);
				String tranAmt=df.format((db_TranAmt/100));
				String tranCommission="0.00";
				String orderNo= tYskPay_db.getSuborderid();
				String orderContent="";

				try{
					Date now = new Date();
					TJzbFreeze tJzbFreeze = new TJzbFreeze();
					tJzbFreeze.setUserid(tYskPay_db.getUserid());
					tJzbFreeze.setSubacctno(tuser.getSubno());
					tJzbFreeze.setTrannetmembercode(tuser.getMembercode());
					tJzbFreeze.setFunctionflag(functionFlag);
					tJzbFreeze.setTranamt(tranAmt);
					tJzbFreeze.setTrancommission(tranCommission);
					tJzbFreeze.setOrderno(orderNo);
					tJzbFreeze.setOrdercontent(orderContent);
					tJzbFreeze.setInsertime(now);
					tJzbFreeze.setUpdatetime(now);
					tJzbFreezeMapper.insertSelective(tJzbFreeze);
				}catch (Exception e){
					e.printStackTrace();
				}

			}

		}

		try{
			//验签
			String sign=params.remove("Signature");
			boolean verify=signService.verify(params,sign,sdkProperties.getPublicKey());
			log.info("验签结果："+verify);
		}catch (Exception e){
		    e.printStackTrace();
		}
		log.debug("payNotifyUrl_end");
		response.addHeader("Content-Type", "text/html;charset=utf-8");
		response.getWriter().write("notify_success");
	}

	@RequestMapping(value = "/jumpUrl",method = RequestMethod.POST)
	public String jumpUrl(HttpServletRequest request, Model model) throws IOException, BizException {
		log.debug("payjumpUrl_beg");
		Map<String,String> params=CusAccessObjectUtil.getAllRequestParam(request);
		log.info(params.toString());
		model.addAttribute("params", params);
		try{
			//验签
			String sign=params.remove("Signature");
			boolean verify=signService.verify(params,sign,sdkProperties.getPublicKey());
			log.info("验签结果："+verify);
		}catch (Exception e){
			e.printStackTrace();
		}
		log.debug("payjumpUrl_end");
		return "ysksdk/jumpUrlToPay";
	}

	private Map<String,String> getJzbQianBaoYuEMap(String yhbm, String subacctno){
		Map<String,String> map_rtn = new HashMap<>();
		//见证子账户可用余额
		String acctavailbal="";
		//见证子账户可提现金额
		String cashamt="";

		//调用见证宝接口获取
		Po6010CustAcctIdBalanceQuery po6010CustAcctIdBalanceQuery = jzbApiService.Api6010CustAcctIdBalanceQuery(subacctno);
		if(po6010CustAcctIdBalanceQuery!=null && "000000".equals(po6010CustAcctIdBalanceQuery.getTxnReturnCode())){
			List<Po6010CustAcctIdBalanceQueryAcctArray> list_po = po6010CustAcctIdBalanceQuery.getAcctArray();
			if(list_po!=null && list_po.size()>=0){
				Po6010CustAcctIdBalanceQueryAcctArray po6010CustAcctIdBalanceQueryAcctArray = list_po.get(0);
				acctavailbal = po6010CustAcctIdBalanceQueryAcctArray.getAcctAvailBal();
				cashamt = po6010CustAcctIdBalanceQueryAcctArray.getCashAmt();
				//充值金额更新用户表
				try{
					TUser tuser_db = tUserMapper.selectByPrimaryKey(Integer.valueOf(yhbm));
					TUser tUser_update = new TUser();
					tUser_update.setYhbm(tuser_db.getYhbm());
					if(acctavailbal!=null && !"".equals(acctavailbal)){
						tUser_update.setTotalmoney(acctavailbal);
					}
					if(cashamt!=null && !"".equals(cashamt)){
						tUser_update.setWithdrawmoney(cashamt);
					}
					tUserMapper.updateByPrimaryKeySelective(tUser_update);
				}catch (Exception e){
					e.printStackTrace();
				}
			}
		}
		map_rtn.put("acctavailbal",acctavailbal);
		map_rtn.put("cashamt",cashamt);
		return map_rtn;
	}

	private Map<String,String> getJzbQianBaoMap(String membercode){
		Map<String,String> map_rtn = new HashMap<>();
		//见证子账户可用余额
		String acctavailbal="";
		//见证子账户可提现金额
		String cashamt="";

		//调用见证宝接口获取
		Po6037QueryCustAcctId po6037QueryCustAcctId = jzbApiService.Api6037QueryCustAcctId(membercode);
		log.debug(JSON.toJSONString(po6037QueryCustAcctId));

		if(po6037QueryCustAcctId!=null && "000000".equals(po6037QueryCustAcctId.getTxnReturnCode())){

			String subAcctFreezeAmt = po6037QueryCustAcctId.getSubAcctFreezeAmt();
			String subAcctCashBal = po6037QueryCustAcctId.getSubAcctCashBal();
			String subAcctAvailBal = po6037QueryCustAcctId.getSubAcctAvailBal();

			Double dbl_subAcctFreezeAmt = 0.0;
			Double dbl_subAcctCashBal = 0.0;
			Double dbl_subAcctAvailBal = 0.0;
			if(subAcctFreezeAmt!=null){ dbl_subAcctFreezeAmt = Double.valueOf(subAcctFreezeAmt);}
			if(subAcctCashBal!=null){ dbl_subAcctCashBal = Double.valueOf(subAcctCashBal);}
			if(subAcctAvailBal!=null){ dbl_subAcctAvailBal = Double.valueOf(subAcctAvailBal);}

			Double dbl_acctavailbal = dbl_subAcctAvailBal+dbl_subAcctFreezeAmt;
			acctavailbal = df.format(dbl_acctavailbal);
			cashamt = df.format(dbl_subAcctCashBal);

		}
		map_rtn.put("acctavailbal",acctavailbal);
		map_rtn.put("cashamt",cashamt);
		return map_rtn;
	}

}
